#include "vzconn/conn/vzserver.h"
#include "vzconn/base/helper.h"
#include "vzconn/conn/tcpserver.h"
#include "vzconn/conn/ipcserver.h"

namespace vzconn {

//////////////////////////////////////////////////////////////////////////////
VzServer::Ptr VzServer::CreateTcpServer(boost::asio::io_service& io_service,
                                        const std::string addr,
                                        uint16 port) {
  LOG(INFO) << "Create Server " << addr << ":" << port;
  return VzServer::Ptr(new TcpServer(io_service, addr, port));
}

VzServer::Ptr VzServer::CreateIpcServer(boost::asio::io_service& io_service,
                                        const std::string addr,
                                        uint16 port) {

#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
  LOG(INFO) << "Create Server " << NetAddrToIpcAddr(addr, port);
  return VzServer::Ptr(new IpcServer(io_service, addr, port));
#else
  port++;
  LOG(INFO) << "Not Support IPC Server, Conver to tcp server";
  LOG(INFO) << "Create Server " << addr << ":" << port;
  return VzServer::Ptr(new TcpServer(io_service, addr, port));
#endif
}
//////////////////////////////////////////////////////////////////////////////

VzServer::VzServer(boost::asio::io_service &io_service)
  : io_service_(io_service),
    stop_(false) {
}

VzServer::~VzServer() {
}

void VzServer::HandleAcceptor(VzConnect::Ptr connect,
                              const boost::system::error_code& err) {
  if(stop_) {
    LOG(WARNING) << "The VzServer was stoped";
    return;
  }
  if(err) {
    Stop();
    LOG(ERROR) << err.message();
    SignalVzServerError(shared_from_this(), err);
    return;
  }
  if(!connect->Start()) {
    LOG(ERROR) << "Failure to start the connect";
    return;
  }
  SignalNewConnect(shared_from_this(), connect);
  WaitNextConnect();
}

void VzServer::Stop() {
  if (stop_) {
    return;
  } else {
    // Fast stop this server
    stop_ = true;
    io_service_.post(
      boost::bind(&VzServer::HandleStopVzServer, shared_from_this()));
  }
}

}